import { ref } from 'vue'
import { useNotification } from './useNotification'
import { useGlobalStore } from '../stores/globalStore'
import { ERROR_CODES } from '../constants'

/**
 * 错误处理组合式函数
 * @returns {Object} 错误处理方法
 */
export function useErrorHandler() {
  const { error: showError, warning: showWarning } = useNotification()
  const globalStore = useGlobalStore()
  
  const errors = ref([])
  const isHandling = ref(false)

  /**
   * 处理错误
   * @param {Error|string} error 错误对象或错误消息
   * @param {Object} context 错误上下文
   * @param {boolean} showToUser 是否显示给用户
   */
  const handleError = (error, context = {}, showToUser = true) => {
    isHandling.value = true

    try {
      const errorInfo = normalizeError(error, context)
      
      // 记录错误
      logError(errorInfo)
      
      // 添加到错误列表
      errors.value.unshift(errorInfo)
      
      // 限制错误列表长度
      if (errors.value.length > 100) {
        errors.value = errors.value.slice(0, 100)
      }
      
      // 显示给用户
      if (showToUser) {
        displayErrorToUser(errorInfo)
      }
      
      // 上报错误（如果有错误上报服务）
      reportError(errorInfo)
      
    } catch (handlingError) {
      console.error('错误处理失败:', handlingError)
    } finally {
      isHandling.value = false
    }
  }

  /**
   * 标准化错误对象
   * @param {Error|string} error 错误
   * @param {Object} context 上下文
   * @returns {Object} 标准化的错误对象
   */
  const normalizeError = (error, context) => {
    const timestamp = new Date().toISOString()
    const id = `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
    
    let errorInfo = {
      id,
      timestamp,
      level: 'error',
      context: {
        url: window.location.href,
        userAgent: navigator.userAgent,
        viewport: {
          width: window.innerWidth,
          height: window.innerHeight
        },
        ...context
      }
    }

    if (error instanceof Error) {
      errorInfo = {
        ...errorInfo,
        name: error.name,
        message: error.message,
        stack: error.stack,
        code: error.code || ERROR_CODES.UNKNOWN_ERROR
      }
    } else if (typeof error === 'string') {
      errorInfo = {
        ...errorInfo,
        name: 'StringError',
        message: error,
        code: ERROR_CODES.UNKNOWN_ERROR
      }
    } else {
      errorInfo = {
        ...errorInfo,
        name: 'UnknownError',
        message: '未知错误',
        code: ERROR_CODES.UNKNOWN_ERROR,
        data: error
      }
    }

    return errorInfo
  }

  /**
   * 记录错误到控制台
   * @param {Object} errorInfo 错误信息
   */
  const logError = (errorInfo) => {
    const logMessage = `[${errorInfo.timestamp}] ${errorInfo.name}: ${errorInfo.message}`
    
    if (errorInfo.level === 'error') {
      console.error(logMessage, errorInfo)
    } else if (errorInfo.level === 'warning') {
      console.warn(logMessage, errorInfo)
    } else {
      console.log(logMessage, errorInfo)
    }
  }

  /**
   * 向用户显示错误
   * @param {Object} errorInfo 错误信息
   */
  const displayErrorToUser = (errorInfo) => {
    const userMessage = getUserFriendlyMessage(errorInfo)
    
    if (errorInfo.level === 'error') {
      showError(userMessage.message, userMessage.title)
    } else if (errorInfo.level === 'warning') {
      showWarning(userMessage.message, userMessage.title)
    }
  }

  /**
   * 获取用户友好的错误消息
   * @param {Object} errorInfo 错误信息
   * @returns {Object} 用户友好的消息
   */
  const getUserFriendlyMessage = (errorInfo) => {
    const errorMessages = {
      [ERROR_CODES.NETWORK_ERROR]: {
        title: '网络错误',
        message: '网络连接失败，请检查网络设置后重试'
      },
      [ERROR_CODES.FILE_TOO_LARGE]: {
        title: '文件过大',
        message: '文件大小超过限制，请选择较小的文件'
      },
      [ERROR_CODES.INVALID_FILE_TYPE]: {
        title: '文件格式错误',
        message: '不支持的文件格式，请选择正确的文件类型'
      },
      [ERROR_CODES.PARSE_ERROR]: {
        title: '数据解析失败',
        message: '文件内容格式错误，请检查文件是否损坏'
      },
      [ERROR_CODES.VALIDATION_ERROR]: {
        title: '数据验证失败',
        message: '输入的数据不符合要求，请检查后重试'
      }
    }

    return errorMessages[errorInfo.code] || {
      title: '操作失败',
      message: errorInfo.message || '发生未知错误，请重试'
    }
  }

  /**
   * 上报错误到服务器
   * @param {Object} errorInfo 错误信息
   */
  const reportError = async (errorInfo) => {
    try {
      // 这里可以集成错误上报服务，如 Sentry、Bugsnag 等
      // await fetch('/api/errors', {
      //   method: 'POST',
      //   headers: { 'Content-Type': 'application/json' },
      //   body: JSON.stringify(errorInfo)
      // })
      
      console.log('错误已记录:', errorInfo.id)
    } catch (reportingError) {
      console.error('错误上报失败:', reportingError)
    }
  }

  /**
   * 处理异步操作错误
   * @param {Promise} promise 异步操作
   * @param {Object} context 错误上下文
   * @returns {Promise} 处理后的Promise
   */
  const handleAsyncError = async (promise, context = {}) => {
    try {
      return await promise
    } catch (error) {
      handleError(error, { ...context, type: 'async' })
      throw error
    }
  }

  /**
   * 创建错误边界
   * @param {Function} fn 要保护的函数
   * @param {Object} context 错误上下文
   * @returns {Function} 包装后的函数
   */
  const createErrorBoundary = (fn, context = {}) => {
    return async (...args) => {
      try {
        return await fn(...args)
      } catch (error) {
        handleError(error, { ...context, type: 'boundary' })
        return null
      }
    }
  }

  /**
   * 处理网络错误
   * @param {Error} error 网络错误
   * @param {Object} requestInfo 请求信息
   */
  const handleNetworkError = (error, requestInfo = {}) => {
    const context = {
      type: 'network',
      ...requestInfo
    }

    if (error.name === 'TypeError' && error.message.includes('fetch')) {
      error.code = ERROR_CODES.NETWORK_ERROR
    }

    handleError(error, context)
  }

  /**
   * 处理文件操作错误
   * @param {Error} error 文件错误
   * @param {Object} fileInfo 文件信息
   */
  const handleFileError = (error, fileInfo = {}) => {
    const context = {
      type: 'file',
      ...fileInfo
    }

    handleError(error, context)
  }

  /**
   * 处理验证错误
   * @param {Array|Object} validationErrors 验证错误
   * @param {Object} context 上下文
   */
  const handleValidationErrors = (validationErrors, context = {}) => {
    const errors = Array.isArray(validationErrors) ? validationErrors : [validationErrors]
    
    errors.forEach(error => {
      const validationError = new Error(error.message || '验证失败')
      validationError.code = ERROR_CODES.VALIDATION_ERROR
      validationError.field = error.field
      
      handleError(validationError, { ...context, type: 'validation' })
    })
  }

  /**
   * 清除错误
   * @param {string} errorId 错误ID
   */
  const clearError = (errorId) => {
    const index = errors.value.findIndex(error => error.id === errorId)
    if (index !== -1) {
      errors.value.splice(index, 1)
    }
  }

  /**
   * 清除所有错误
   */
  const clearAllErrors = () => {
    errors.value = []
  }

  /**
   * 获取错误统计
   * @returns {Object} 错误统计信息
   */
  const getErrorStats = () => {
    const now = new Date()
    const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000)
    const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000)

    const recentErrors = errors.value.filter(error => 
      new Date(error.timestamp) > oneHourAgo
    )
    
    const dailyErrors = errors.value.filter(error => 
      new Date(error.timestamp) > oneDayAgo
    )

    const errorsByType = errors.value.reduce((acc, error) => {
      acc[error.code] = (acc[error.code] || 0) + 1
      return acc
    }, {})

    return {
      total: errors.value.length,
      recent: recentErrors.length,
      daily: dailyErrors.length,
      byType: errorsByType
    }
  }

  return {
    errors,
    isHandling,
    handleError,
    handleAsyncError,
    createErrorBoundary,
    handleNetworkError,
    handleFileError,
    handleValidationErrors,
    clearError,
    clearAllErrors,
    getErrorStats
  }
}

/**
 * 全局错误处理器
 */
export function setupGlobalErrorHandler() {
  const { handleError } = useErrorHandler()

  // 捕获未处理的JavaScript错误
  window.addEventListener('error', (event) => {
    handleError(event.error || new Error(event.message), {
      type: 'javascript',
      filename: event.filename,
      lineno: event.lineno,
      colno: event.colno
    })
  })

  // 捕获未处理的Promise拒绝
  window.addEventListener('unhandledrejection', (event) => {
    handleError(event.reason, {
      type: 'promise'
    })
  })

  // Vue错误处理
  const app = getCurrentInstance()?.appContext.app
  if (app) {
    app.config.errorHandler = (error, instance, info) => {
      handleError(error, {
        type: 'vue',
        component: instance?.$options.name || 'Unknown',
        info
      })
    }
  }
}



